#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>

#define N 400
#define XSIZE 800
#define YSIZE 600
#define F_SIZE 16
#define NAME "Abho: "
#define BUF_SIZ 4096

int send_request( int sock,char string2[N])
{int laenge;
    char request[BUF_SIZ];
    printf("%s",string2);
    snprintf(request, sizeof(request), " %s \n\r",string2);
    printf("send_request: %s",request);

 
    
    if (send(sock, request, strlen(request), 0) == -1)
    {
        perror("send() failed");
        return 1;
    }
    
    return 0;
}

int view_response( int sock)
{
    char response[BUF_SIZ];
    int bytes;

    bytes = recv(sock, response, sizeof(response), 0); 
    printf(" %s ", response);

    if (bytes < 0)
    {
        perror("recv() failed");
        return 1;
    }

    return 0;
}


void stringmalen(SDL_Surface *screen,TTF_Font *font,char string[N],int anfang,int ende,int x, int y)
{ int i;SDL_Color color = { 0, 255, 0 };
  char string2[80]={0},string3[2]={0};int weight=0;

 for(i=anfang;i<ende;i++)
       {
	 string2[strlen(string2)]=string[i];

       }
 printf("string %s \n ",string);
  for (i=0;i<ende-anfang;i++)
   {
     string3[0]=string2[i];
     string3[1]=0;
     SDL_Surface *textSurface =  TTF_RenderText_Blended(font, string3, color);
     weight=textSurface->w;     
     SDL_Rect textLocation = { x, y, weight, 16 };
     SDL_FillRect(screen,&textLocation,SDL_MapRGB(screen->format,0,0,0));
     SDL_BlitSurface(textSurface, NULL, screen, &textLocation);
    
     SDL_FreeSurface(textSurface);x=x+weight;
   }  
       
}

void einsortieren(int A[N],int weight,int pos)
{
 int i=0,b=1;
 A[1]=A[1]+1;
 for (i=A[1];i>pos;i--)
       {
	 A[i+1]=A[i];
       }
 A[pos+2]=weight;
 A[0]=14;
 for(i=2;i<A[1]+2;i++)
       {
	 A[0]=A[0]+A[i];printf("%d, weight %d\n",i,A[i]);
       }

}

void bschreiben2(SDL_Surface *screen, Uint16 muh,TTF_Font *font,char string[N],int A[N],int S[2],int fR, int fG, int fB)
{ char string1[2];
  int weight,i=0,rstring=0,astring=0,sanfang=0,sx,sy,sende=0;

 SDL_Color color = { fR, fG, fB };
 SDL_Surface *textSurface;
 
rstring=S[1];
 astring=A[1];
   
 for (i=astring+1;i>rstring;i--)
   {
     string[i]=string[i-1];
     printf("muh\n");
   }

 string[rstring]=(char)muh;
 string[(astring+1)]='\0';
 string1[0]=(char)muh;
 string1[1]='\0';
 
  textSurface =  TTF_RenderText_Blended(font, string1, color);

  weight=textSurface->w;
  if(A[0]+weight<XSIZE-22)
    {einsortieren(A,weight,S[1]);
   
  sanfang=S[1];
  S[1]=S[1]+1; ;
  sende=A[1];
  sx=S[0];
  sy=280;

  stringmalen(screen,font,string, sanfang, sende, sx,sy );

  S[0]=S[0]+weight;}
  SDL_FreeSurface(textSurface);
}

void loeschen(SDL_Surface *screen, TTF_Font *font,char string[N], int A[N],int S[2],int r)
{

  int i,x,y; 
  A[0]=A[0]-A[S[1]+1+r];if(r==0)S[0]=S[0]-A[S[1]+1];
  for (i=S[1]+r;i<A[1]+1+r;i++)
    {A[i+1]=A[i+2];string[i-1]=string[i];}
  A[1]=A[1]-1;if(r==0)S[1]=S[1]-1;
  x=S[0];
  y=280;
  SDL_Rect rect1= {S[0] , 282,XSIZE-2*x ,13 };
  SDL_FillRect(screen,&rect1,SDL_MapRGB(screen->format,0,0,0));
  stringmalen(screen,font,string,S[1],A[1],x,y);
  

}

void curserbewegen(char string[N],int A[N],int S[2],int r)
{int i,m=28;
  
  if(r==-1)
    {
      for(i=2;i<A[1]+2;i++)
	{
	  m=m+A[i];
	  if(m==S[0])
	    {
	      S[0]=S[0]+(A[i]*r);
	      S[1]=S[1]+(1*r);
	      break;
	    }
	}

    }
  else
    { for(i=2;i<A[1]+2;i++)
	{
	  if(m==S[0])
	    {
	      S[0]=S[0]+(A[i]*r);
	      S[1]=S[1]+(1*r);
	      break;
	    }
	  else
	    {
	      m=m+A[i];
	    }
	}
    }
}

void fertig(SDL_Surface *screen, TTF_Font *font,char string[N],int A[N],int S[N],int x,int y, int sock)
{
  char string2[N]=NAME;
  int laenge,i;
  strcat(string2,string);
  laenge=strlen(string2);
  SDL_Rect rect1 = { 0+x, 0+28,XSIZE-x , y };
  SDL_Rect rect2 = { 0+x, 0,XSIZE-x , y };
  SDL_Rect rect3 = { 0+x, 280,XSIZE-2*x ,16  };
  SDL_Rect rect4 = { 0+x, y,XSIZE-x , 16 };
  SDL_BlitSurface(screen,&rect1,screen,&rect2);
  SDL_FillRect(screen,&rect4,SDL_MapRGB(screen->format,0,0,0));
  stringmalen(screen,font,string2,0,laenge, x,y);
send_request(sock,string2);  
for(i=2;i<A[1]+2;i++)
    {A[i]=0;string[i-2]=0;}
  A[0]=28;
  A[1]=0;
  S[0]=28;
  S[1]=0;
  SDL_FillRect(screen,&rect3,SDL_MapRGB(screen->format,0,0,0));
  
}

int main (int argc, char *argv[])
{

  SDL_Surface *screen, *background, *textfeld, *curser;
  SDL_Rect back_dst,text_dst,curser_dst;
  SDL_Event event;
  TTF_Font *font;
  SDL_KeyboardEvent k_down;
  char string[N];
  int muh=0,muh1=0,done=0,x=28,y=240,i;
  int A[N]={0},S[2]={28,0};
  int s, c;
  socklen_t addr_len;
  struct sockaddr_in addr;

  A[0]=28;
 
 
 if (SDL_Init(SDL_INIT_VIDEO) == -1)
   {
     printf("Can't init SDL:  %s\n", SDL_GetError());
     exit(1);
   }
 
 atexit(SDL_Quit);
 screen = SDL_SetVideoMode(XSIZE, YSIZE, 32, SDL_HWSURFACE| SDL_DOUBLEBUF);

 if (screen == NULL)
   {
     printf("Can't set video mode: %s\n", SDL_GetError());
     exit(1);
   }

 TTF_Init();
 
 font = TTF_OpenFont("arial.ttf", F_SIZE);

 
 SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 0));

  background=SDL_LoadBMP("background5.bmp");
  curser=SDL_LoadBMP("strich.bmp");

 if (curser==NULL)
    {
      printf("%s\n", SDL_GetError());
      exit(1);
    }	
  
  back_dst.x=0;
  back_dst.y=0;
  back_dst.w=background->w;
  back_dst.h=background->h;
  curser_dst.x=28;curser_dst.y=280;curser_dst.w=curser->w;
  curser_dst.h=curser->h;
  SDL_WM_SetCaption("CHAT!", NULL);
  
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 0)); 


  SDL_BlitSurface(background,0,screen,&back_dst);
  SDL_BlitSurface(curser,0,screen,&curser_dst);

  printf("muh");
  s = socket(PF_INET, SOCK_STREAM, 0);
    if (s == -1)
    {
        perror("socket() failed");
        return 1;
    }

    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(1234);
    addr.sin_family = AF_INET;

    if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
    {
        perror("bind() failed");
        return 2;
    }

    if (listen(s, 3) == -1)
    {
        perror("listen() failed");
        return 3;
    }
    
    
      printf(" server sockel listen\n");
      addr_len = sizeof(addr);
      c = accept(s, (struct sockaddr*)&addr, &addr_len);
 muh=SDL_EnableKeyRepeat(500,20);
 SDL_EnableUNICODE(1);
 while(!done)
   {
     

     
     if(muh1>4)
	    {SDL_BlitSurface(curser,NULL,screen,&curser_dst);muh++;}
	  else muh1++;
	  if(muh>4)
	    {SDL_FillRect(screen,&curser_dst,SDL_MapRGB(screen->format,0,0,0));
	      muh1=0;muh=0;}

     while (SDL_PollEvent(&event))
       {
	 switch(event.type)
	   {
	   case SDL_QUIT:
	     done = 1;
	     break;
	   case SDL_KEYDOWN:
	     

	     if((event.key.keysym.unicode>=32)&&(event.key.keysym.unicode<=126)|(event.key.keysym.unicode>=160)&&(event.key.keysym.unicode<=255))
	       {  bschreiben2(screen,event.key.keysym.unicode,font,string,A,S,0,255,0);}
	     SDL_FillRect(screen,&curser_dst,SDL_MapRGB(screen->format,0,0,0));
	     curser_dst.x=S[0];
	     switch(event.key.keysym.sym)
	       {
	       case SDLK_ESCAPE:
		 done=1;
		 break;

	       case SDLK_RETURN:
		 
		 fertig(screen,font,string, A,S,x,y,c);
		 curser_dst.x=S[0];
		 
		
		   
		 if(view_response(c))
		   return 6;		 
		 break;
	 
	       case SDLK_BACKSPACE:
		 if(S[1]!=0)
		   {loeschen(screen,font,string, A, S,0);
		     curser_dst.x=S[0];}		 
		 break;

	       case SDLK_DELETE:
		 if(S[1]<A[1]) 
		   {loeschen(screen,font,string, A, S,1);
		     curser_dst.x=S[0];}	 
	       printf("muh");
		 break;

	       case SDLK_LEFT:
		 if(S[1]>0)
		   { 
		     curserbewegen(string,A,S,-1);
		     SDL_FillRect(screen,&curser_dst,SDL_MapRGB(screen->format,0,0,0));
		     curser_dst.x=S[0];
		   }break;
	       case SDLK_RIGHT:
		 if(S[1]<A[1])
		   {
		     curserbewegen(string,A,S,1);
		     SDL_FillRect(screen,&curser_dst,SDL_MapRGB(screen->format,0,0,0));
		     curser_dst.x=S[0];
		   }break;
	       }
	   }
       }
      SDL_Flip(screen);
      SDL_Delay(1);
     
   }
 close(c);
 
 
 close(s);
  SDL_FreeSurface(screen);
 SDL_FreeSurface(background);
 TTF_Quit();
 return 0;
}
